home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / xrdb.c < prev   
C/C++ Source or Header  |  1993-05-22  |  11KB  |  526 lines

  1. #ifdef HAVE_X11_X_H
  2. /* Deal with the X Resource Manager.
  3.    Copyright (C) 1990, 1992, 1993 Free Software Foundation.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /* Coopted for oleo -t 12/92 */
  20. /* Written by jla, 4/90 */
  21.  
  22. #ifndef alloca
  23. #ifdef __GNUC__
  24. #define alloca __builtin_alloca
  25. #else /* __GNUC__ not defined.  */
  26. #if HAVE_ALLOCA_H
  27. #include <alloca.h>
  28. #else /* not HAVE_ALLOCA_H */
  29. #if defined (MSDOS) && !defined (__TURBOC__)
  30. #include <malloc.h>
  31. #else /* not MSDOS, or __TURBOC__ */
  32. #if defined(_AIX)
  33. #include <malloc.h>
  34.  #pragma alloca
  35. #endif /* not _AIX */
  36. #endif /* not MSDOS, or __TURBOC__ */
  37. #endif /* not HAVE_ALLOCA_H */
  38. #endif /* __GNUC__ not defined.  */
  39. #endif /* alloca not defined.  */
  40.  
  41. #include <stdio.h>
  42. #include "sysdef.h"
  43.  
  44. /* This should be included before the X include files; otherwise, we get
  45.    warnings about redefining NULL under BSD 4.3.  */
  46. #include <sys/param.h>
  47. #define NeedFunctionPrototypes 0
  48. #include <X11/X.h>
  49. #include <X11/Xlib.h>
  50. #include <X11/Xutil.h>
  51. #include <X11/Xatom.h>
  52. #include <X11/Xresource.h>
  53. #ifdef VMS
  54. #include "vms-pwd.h"
  55. #else
  56. #include <pwd.h>
  57. #endif
  58.  
  59. /*
  60.  * Already included <sys/stat.h> via sysdef.h
  61.  */
  62.  
  63. #if !defined(S_ISDIR) && defined(S_IFDIR)
  64. #define       S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
  65. #endif
  66.  
  67.  
  68. #ifndef MAXPATHLEN
  69. #define MAXPATHLEN    256
  70. #endif
  71.  
  72. extern char *getenv ();
  73. extern struct passwd *getpwuid ();
  74. extern struct passwd *getpwnam ();
  75.  
  76. static char *
  77. gethomedir (dirname)
  78.      char *dirname;
  79. {
  80.   int uid;
  81.   struct passwd *pw;
  82.   char *ptr;
  83.  
  84.   if ((ptr = getenv ("HOME")) == NULL)
  85.     {
  86.       if ((ptr = getenv ("USER")) != NULL)
  87.     pw = getpwnam (ptr);
  88.       else
  89.     {
  90.       uid = getuid ();
  91.       pw = getpwuid (uid);
  92.     }
  93.       if (pw)
  94.     ptr = pw->pw_dir;
  95.       else
  96.     {
  97.       ptr = NULL;
  98.       *dirname = '\0';
  99.     }
  100.     }
  101.  
  102.   if (ptr != NULL) 
  103.     strcpy (dirname, ptr);
  104.  
  105.   dirname += strlen (dirname);
  106.   *dirname = '/';
  107.   dirname++;
  108.   *dirname = '\0';
  109.  
  110.   return dirname;
  111. }
  112.  
  113. static int
  114. file_p (path)
  115.      char *path;
  116. {
  117.   struct stat status;
  118.  
  119.   return (access (path, 4) == 0            /* exists and is readable */
  120.       && stat (path, &status) == 0        /* get the status */
  121.       && !S_ISDIR(status.st_mode));
  122. }
  123.  
  124.  
  125. /* Isn't this just disgusting? */
  126.  
  127. #define X_DEFAULT_SEARCH_PATH "/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S"
  128.  
  129. static int
  130. decode_magic (string, file, return_path)
  131.      char *string, *file, *return_path;
  132. {
  133.   char *p = string;
  134.   char *t = return_path;
  135.  
  136.   while (*p)
  137.     {
  138.       if (*p == '%')
  139.     switch (*++p)
  140.       {
  141.       case '%':
  142.         *t++ = '%';
  143.         p++;
  144.         break;
  145.  
  146.       case 'N':
  147.       case 'T':
  148.       case 'S':
  149.       case 'L':
  150.       case 'l':
  151.       case 't':
  152.       case 'c':
  153.       default:
  154.         p++;
  155.         if (*t == '/' && *p == '/')
  156.           p++;
  157.         break;
  158.       }
  159.       else
  160.     *t++ = *p++;
  161.     }
  162.   *t = '\0';
  163.   strcat (return_path, file);
  164.  
  165.   if (file_p (return_path))
  166.     return 1;
  167.  
  168.   return_path[0] = '\0';
  169.   return 0;
  170. }
  171.  
  172. static int
  173. magic_searchpath_decoder (incantation_string, file, return_path)
  174.      char *incantation_string, *return_path, *file;
  175. {
  176.   register char *s = incantation_string;
  177.   register char *p;
  178.  
  179.   /* Must be big enough for "%N%S".  */
  180.   register int string_size = MAXPATHLEN;
  181.   register char *string = (char *) alloca (string_size * sizeof (*string));
  182.  
  183.   while (*s)
  184.     {
  185.       p = s;
  186.  
  187.       while (*p && *p != ':')
  188.     p++;
  189.  
  190.       if (p == s)
  191.     {
  192.       /* We know string is big enough for this.  */
  193.       bcopy ("%N%S", string, 5);
  194.       if (decode_magic (string, file, return_path))
  195.         return 1;
  196.     }
  197.       else
  198.     {
  199.       int len = p - s;
  200.  
  201.       if (string_size < len+1)
  202.         {
  203.           string_size = 2 * len;
  204.           string = (char *) alloca (string_size * sizeof (*string));
  205.         }
  206.       bcopy (s, string, len);
  207.       string[len + 1] = '\0';
  208.       if (decode_magic (string, file, return_path))
  209.         return 1;
  210.     }
  211.  
  212.       if (*p)
  213.     s = p + 1;
  214.       else
  215.     return 0;
  216.     }
  217.  
  218.   return 0;
  219. }
  220.  
  221. static XrmDatabase
  222. get_system_app (class)
  223.      char *class;
  224. {
  225.   XrmDatabase db;
  226.   char path[MAXPATHLEN];
  227.   char *p;
  228.  
  229.   if ((p = getenv ("XFILESEARCHPATH")) == NULL)
  230.     p = X_DEFAULT_SEARCH_PATH;
  231.  
  232.   if (! magic_searchpath_decoder (p, class, path))
  233.     return NULL;
  234.  
  235.   db = XrmGetFileDatabase (path);
  236.   return db;
  237. }
  238.  
  239. static XrmDatabase
  240. get_fallback (display)
  241.      Display *display;
  242. {
  243.   return NULL;
  244. }
  245.  
  246. static XrmDatabase
  247. get_user_app (class)
  248.      char *class;
  249. {
  250.   XrmDatabase db;
  251.   char *magic_path;
  252.   char path[MAXPATHLEN];
  253.  
  254.   if ((magic_path = getenv ("XUSERFILESEARCHPATH")) == NULL)
  255.     {
  256.       char homedir[MAXPATHLEN];
  257.       char *default_magic;
  258.       char *p;
  259.  
  260.       gethomedir (homedir);
  261.  
  262.       if ((p = getenv ("XAPPLRESDIR")) == NULL)
  263.     {
  264.       default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N";
  265.       magic_path = (char *) alloca ((3 * strlen (homedir))
  266.                     + strlen (default_magic));
  267.       sprintf (magic_path, default_magic, homedir, homedir, homedir);
  268.     }
  269.       else
  270.     {
  271.       default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N";
  272.       magic_path = (char *) alloca ((3 * strlen (p))
  273.                     + strlen (default_magic)
  274.                     + strlen (homedir));
  275.       sprintf (magic_path, default_magic, p, p, p, homedir);
  276.     }
  277.     }
  278.  
  279.   if (! magic_searchpath_decoder (magic_path, class, path))
  280.     return NULL;
  281.   
  282.   db = XrmGetFileDatabase (path);
  283.   return db;
  284. }
  285.  
  286. static XrmDatabase
  287. get_user_db (display)
  288.      Display *display;
  289. {
  290.   XrmDatabase db;
  291.   char *xdefs;
  292.  
  293. #ifdef HAVE_X11R4
  294.   xdefs = XResourceManagerString (display);
  295. #else
  296.   xdefs = display->xdefaults;
  297. #endif
  298.  
  299.   if (xdefs != NULL)
  300.     db = XrmGetStringDatabase (xdefs);
  301.   else
  302.     {
  303.       char xdefault[MAXPATHLEN];
  304.  
  305.       gethomedir (xdefault);
  306.       strcat (xdefault, ".Xdefaults");
  307.       db = XrmGetFileDatabase (xdefault);
  308.     }
  309.  
  310.   return db;
  311. }
  312.  
  313. static XrmDatabase
  314. get_environ_db ()
  315. {
  316.   XrmDatabase db;
  317.   char *p;
  318.   char path[MAXPATHLEN];
  319.  
  320.   if ((p = getenv ("XENVIRONMENT")) == NULL)
  321.     {
  322.       gethomedir (path);
  323.       strcat (path, ".Xdefaults-");
  324.       gethostname (path + strlen (path), MAXPATHLEN - strlen (path));
  325.       p = path;
  326.     }
  327.  
  328.   db = XrmGetFileDatabase (p);
  329.   return db;
  330. }
  331.  
  332. /* Types of values that we can find in a database */
  333.  
  334. #define XrmStringType "String"    /* String representation */
  335. XrmRepresentation x_rm_string = 0;    /* Quark representation */
  336.  
  337. /* Load X resources based on the display and a possible -xrm option. */
  338.  
  339. XrmDatabase
  340. x_load_resources (display, xrm_string, myclass)
  341.      Display *display;
  342.      char *xrm_string, *myclass;
  343. {
  344.   XrmDatabase rdb;
  345.   XrmDatabase db;
  346.  
  347.   if (!x_rm_string)
  348.     x_rm_string = XrmStringToQuark (XrmStringType);
  349.  
  350.   XrmInitialize ();
  351.   rdb = XrmGetStringDatabase ("");
  352.  
  353.   /* Get application system defaults */
  354.   db = get_system_app (myclass);
  355.   if (db != NULL)
  356.     XrmMergeDatabases (db, &rdb);
  357.  
  358.   /* Get Fallback resources */
  359.   db = get_fallback (display);
  360.   if (db != NULL)
  361.     XrmMergeDatabases (db, &rdb);
  362.  
  363.   /* Get application user defaults */
  364.   db = get_user_app (myclass);
  365.   if (db != NULL)
  366.     XrmMergeDatabases (db, &rdb);
  367.  
  368.   /* get User defaults */
  369.   db = get_user_db (display);
  370.   if (db != NULL)
  371.     XrmMergeDatabases (db, &rdb);
  372.  
  373.   /* Get Environment defaults. */
  374.   db = get_environ_db ();
  375.   if (db != NULL)
  376.     XrmMergeDatabases (db, &rdb);
  377.   
  378.   /* Last, merge in any specification from the command line. */
  379.   if (xrm_string != NULL)
  380.     {
  381.       db = XrmGetStringDatabase (xrm_string);
  382.       if (db != NULL)
  383.     XrmMergeDatabases (db, &rdb);
  384.     }
  385.  
  386.   return rdb;
  387. }
  388.  
  389. /* Retrieve the value of the resource specified by NAME with class CLASS
  390.    and of type TYPE from database RDB.  The value is returned in RET_VALUE. */
  391.  
  392. int
  393. x_get_resource (rdb, name, class, expected_type, ret_value)
  394.      XrmDatabase rdb;
  395.      char *name, *class;
  396.      XrmRepresentation expected_type;
  397.      XrmValue *ret_value;
  398. {
  399.   XrmValue value;
  400.   XrmName namelist[100];
  401.   XrmClass classlist[100];
  402.   XrmRepresentation type;
  403.  
  404.   XrmStringToNameList(name, namelist);
  405.   XrmStringToClassList(class, classlist);
  406.  
  407.   if (XrmQGetResource (rdb, namelist, classlist, &type, &value) == True
  408.       && (type == expected_type))
  409.     {
  410.       if (type == x_rm_string)
  411.     ret_value->addr = (char *) value.addr;
  412.       else
  413.     bcopy (value.addr, ret_value->addr, ret_value->size);
  414.  
  415.       return value.size;
  416.     }
  417.  
  418.   return 0;
  419. }
  420.  
  421. /* Retrieve the string resource specified by NAME with CLASS from
  422.    database RDB. */
  423.  
  424. char *
  425. x_get_string_resource (rdb, name, class)
  426.      XrmDatabase rdb;
  427.      char *name, *class;
  428. {
  429.   XrmValue value;
  430.  
  431.   if (!x_rm_string)
  432.     x_rm_string = XrmStringToQuark (XrmStringType);
  433.  
  434.   if (x_get_resource (rdb, name, class, x_rm_string, &value))
  435.     return (char *) value.addr;
  436.  
  437.   return (char *) 0;
  438. }
  439.  
  440. #ifdef TESTRM
  441. #include <stdio.h>
  442. #include "arg-list.h"
  443.  
  444. static void
  445. fatal (msg, prog, x1, x2, x3, x4, x5)
  446.     char *msg, *prog;
  447.     int x1, x2, x3, x4, x5;
  448. {
  449.     extern int errno;
  450.  
  451.     if (errno)
  452.       perror (prog);
  453.  
  454.     (void) fprintf (stderr, msg, prog, x1, x2, x3, x4, x5);
  455.     exit (1);
  456. }
  457.  
  458. main (argc, argv)
  459.     int argc;
  460.     char **argv;
  461. {
  462.   Display *display;
  463.   char *displayname, *resource_string, *class;
  464.   XrmDatabase xdb;
  465.   List *arg_list, *lp;
  466.  
  467.   arg_list = arg_listify (argc, argv);
  468.  
  469.   lp = member ("-d", arg_list);
  470.   if (!NIL (lp))
  471.     displayname = car (cdr (lp));
  472.   else
  473.     displayname = "localhost:0.0";
  474.  
  475.   lp = member ("-xrm", arg_list);
  476.   if (! NIL (lp))
  477.     resource_string = car (cdr (lp));
  478.   else
  479.     resource_string = (char *) 0;
  480.  
  481.   lp = member ("-c", arg_list);
  482.   if (! NIL (lp))
  483.     class = car (cdr (lp));
  484.   else
  485.     class = "Emacs";
  486.  
  487.   free_arglist (arg_list);
  488.  
  489.  
  490.  
  491.   if (!(display = XOpenDisplay (displayname)))
  492.     fatal ("Can't open display '%s'\n", XDisplayName (displayname));
  493.  
  494.   xdb = x_load_resources (display, resource_string, class);
  495.  
  496. #if 0
  497.   /* In a real program, you'd want to also do this: */
  498.   display->db = xdb;
  499. #endif
  500.  
  501.   while (1)
  502.     {
  503.       char line[90];
  504.  
  505.       printf ("String: ");
  506.       gets (line);
  507.       if (strlen (line))
  508.     {
  509.       char *value = x_get_string_resource (xdb, line, class);
  510.  
  511.       if (value != NULL)
  512.         printf ("\t%s:  %s\n\n", line, value);
  513.       else
  514.         printf ("\tNo Value.\n\n");
  515.     }
  516.       else
  517.     break;
  518.     }
  519.   printf ("\tExit.\n\n");
  520.  
  521.   XCloseDisplay (display);
  522. }
  523. #endif /* TESTRM */
  524. #endif /* HAVE_X11_X_H */
  525.  
  526.